// SDPContent.cpp: implementation of the CSDPContent class.
//
//////////////////////////////////////////////////////////////////////
#pragma warning(disable:4530)

#include "SDPContent.h"

#ifdef USE_DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSDPContent::CSDPContent()
{
	version = 0;	
	//mystring				sessionname;
	//mystring				sessiondescription;
	//mystring				uri;
	//mystring				emailaddress;
	//mystring				phonenumber;
	origin = NULL;
	connection = NULL;
	bandwidth = NULL;
	times = NULL;
	repeattimes = NULL;
}

CSDPContent::~CSDPContent()
{
	Clear();
}
void CSDPContent::Clear()
{
	if(origin)
	{
		delete origin;
		origin = NULL;
	}
	if(connection)
	{
		delete connection;
		connection = NULL;
	}
	if(bandwidth)
	{
		delete bandwidth;
		bandwidth = NULL;
	}
	if(times)
	{
		delete times;
		times = NULL;
	}
	if(repeattimes)
	{
		delete repeattimes;
		repeattimes = NULL;
	}
	while(medialist.empty() == false)
	{
		delete medialist.front();
		medialist.pop_front();
	}
	while(attributelist.empty() == false)
	{
		attributelist.pop_front();
	}

}

void CSDPContent::SetContent(const char *pbuf,int len)
{
	CSIPContent::SetContent(pbuf,len);
	Parse(m_pContent,m_nLength);
}

mystring CSDPContent::Encoding()
{
	mystring en;
	char buf[64];
	sprintf(buf,"%d",version);
	en = "v=";
	en += buf;
	en +="\r\n";
	if(origin)
	{
		en += "o=";
		en += origin->username;
		en += " ";
		sprintf(buf,"%d",origin->sessionid);
		en += buf;
		en += " ";
		sprintf(buf,"%d",origin->version);
		en += buf;
		en += " ";
		en += origin->networktype;
		en += " ";
		en += origin->addresstype;
		en += " ";
		en += origin->address;
		en += "\r\n";
	}
	if(sessionname.empty() == false)
	{
		en += "s=" + sessionname;
		en += "\r\n";
	}
	if(sessiondescription.empty() == false)
	{
		en += "i=" + sessiondescription;
		en += "\r\n";
	}
	if(connection)
	{
		en += "c=";
		en += connection->networktype;
		en += " ";
		en += connection->addresstype;
		en += " ";
		en += connection->connectionaddress;
		if(connection->ttl > 0)
		{
			en += "/";
			sprintf(buf,"%d",connection->ttl);
			en += buf;
			if(connection->numberofaddress > 0)
			{
				en += "/";
				sprintf(buf,"%d",connection->numberofaddress);
				en += buf;
			}
		}
		en += "\r\n";
	}
	if(uri.empty() == false)
	{
		en += "u=" + uri;
		en += "\r\n";
	}
	if(emailaddress.empty() == false)
	{
		en += "e=" + emailaddress;
		en += "\r\n";
	}
	if(phonenumber.empty() == false)
	{
		en += "p=" + phonenumber;
		en += "\r\n";
	}
	if(bandwidth)
	{
		en += "b=" + bandwidth->modifier;
		sprintf(buf,"%d",bandwidth->bandwidthvalue);
		en += buf;
		en += "\r\n";
	}
	list<struct Attribute>::iterator ai;
	for(ai = attributelist.begin();ai != attributelist.end();ai++)
	{
		en += "a=";
		en += ai->att_field;
		if(ai->att_value.empty() == false)
		{
			en += ":" + ai->att_value;
		}
		en += "\r\n";
	}
	list<struct MediaDescription*>::iterator mi;
	for(mi = medialist.begin();mi != medialist.end();mi++)
	{
		en += "m=" + (*mi)->media.media;
		en += " ";
		sprintf(buf,"%d",(*mi)->media.port);
		en += buf;
		if((*mi)->media.numberofport > 0)
		{
			sprintf(buf,"%d",(*mi)->media.numberofport);
			en +="/";
			en += buf;
		}
		en += " ";
		en += (*mi)->media.transport;
		if((*mi)->media.formatlist.size() > 0)
		{
			list<mystring>::iterator fi;
			for(fi = (*mi)->media.formatlist.begin();fi != (*mi)->media.formatlist.end();fi++)
				en += " " + *fi;
		}
		en += "\r\n";
		if((*mi)->connection)
		{
			en += "c=";
			en += (*mi)->connection->networktype;
			en += " ";
			en += (*mi)->connection->addresstype;
			en += " ";
			en += (*mi)->connection->connectionaddress;
			if((*mi)->connection->ttl > 0)
			{
				en += "/";
				sprintf(buf,"%d",(*mi)->connection->ttl);
				en += buf;
				if((*mi)->connection->numberofaddress > 0)
				{
					en += "/";
					en += buf;
				}
			}
			en += "\r\n";
		}
		if((*mi)->mediatitle.empty() == false)
		{
			en += "i=" + (*mi)->mediatitle;
			en += "\r\n";
		}
		if((*mi)->bandwidth)
		{
			en += "b=" + (*mi)->bandwidth->modifier;
			sprintf(buf,"%d",(*mi)->bandwidth->bandwidthvalue);
			en += buf;
			en += "\r\n";
		}
		for(ai = (*mi)->attributelist.begin();ai != (*mi)->attributelist.end();ai++)
		{
			en += "a=";
			en += ai->att_field;
			if(ai->att_value.empty() == false)
			{
				en += ":" + ai->att_value;
			}
			en += "\r\n";
		}
	}
	if(m_pContent)
		delete[] m_pContent;
	m_pContent = new char[en.length()+1];
	strcpy(m_pContent,en.c_str());
	m_nLength = en.length();
	return en;
}
int skipequal(const char *p,int len)
{
	int c = 0;
	while(*p != '=')
	{
		p++;
		c++;
		if(c >= len)
			return -1;
	}
	p++;c++;
	return c;
}
int CSDPContent::Parse(const char *pbuf, int len)
{
	const char *p = pbuf;
	int c = 0,c1;
	while(p)
	{
		switch(*p)
		{
		case 'v'://version
			{
				p++;
				c++;
				c1 = skipequal(p,len - c);
				if(c1 == -1)
					return -1;
				p+=c1;
				c+=c1;
				c1 = ParseVersion(p,len-c,version);
				if(c1 == -1)
					return -1;
				c+=c1;
				p+=c1;
			}
			break;
		case 'o'://origin
			{
				p++;
				c++;
				c1 = skipequal(p,len - c);
				if(c1 == -1)
					return -1;
				p+=c1;
				c+=c1;
				if(origin == NULL)
					origin = new struct Origin;
				c1 = ParseOrigin(p,len-c,*origin);
				if(c1 == -1)
					return -1;
				c+=c1;
				p+=c1;
			}
			break;
		case 's'://session name
			{
				p++;
				c++;
				c1 = skipequal(p,len - c);
				if(c1 == -1)
					return -1;
				p+=c1;
				c+=c1;
				c1 = ParseSessionName(p,len-c,sessionname);
				if(c1 == -1)
					return -1;
				c+=c1;
				p+=c1;
			}
			break;
		case 'i'://session information
			{
				p++;
				c++;
				c1 = skipequal(p,len - c);
				if(c1 == -1)
					return -1;
				p+=c1;
				c+=c1;
				c1 = ParseSessionDescription(p,len-c,sessiondescription);
				if(c1 == -1)
					return -1;
				c+=c1;
				p+=c1;
			}
			break;
		case 'u'://uri
			{
				p++;
				c++;
				c1 = skipequal(p,len - c);
				if(c1 == -1)
					return -1;
				p+=c1;
				c+=c1;
				c1 = ParseURI(p,len-c,uri);
				if(c1 == -1)
					return -1;
				c+=c1;
				p+=c1;
			}
			break;
		case 'e'://email
			{
				p++;
				c++;
				c1 = skipequal(p,len - c);
				if(c1 == -1)
					return -1;
				p+=c1;
				c+=c1;
				c1 = ParseEMail(p,len-c,emailaddress);
				if(c1 == -1)
					return -1;
				c+=c1;
				p+=c1;
			}
			break;
		case 'p'://phone number
			{
				p++;
				c++;
				c1 = skipequal(p,len - c);
				if(c1 == -1)
					return -1;
				p+=c1;
				c+=c1;
				c1 = ParsePhoneNumber(p,len-c,phonenumber);
				if(c1 == -1)
					return -1;
				c+=c1;
				p+=c1;
			}
			break;
		case 'c'://connection information
			{
				p++;
				c++;
				c1 = skipequal(p,len - c);
				if(c1 == -1)
					return -1;
				p+=c1;
				c+=c1;
				if(connection == NULL)
					connection = new struct Connection;
				c1 = ParseConnectionInformation(p,len-c,*connection);
				if(c1 == -1)
					return -1;
				c+=c1;
				p+=c1;
			}
			break;
		case 'b'://bandwidth
			{
				p++;
				c++;
				c1 = skipequal(p,len - c);
				if(c1 == -1)
					return -1;
				p+=c1;
				c+=c1;
				if(bandwidth == NULL)
					bandwidth = new struct Bandwidth;
				c1 = ParseBandwidthInformation(p,len-c,*bandwidth);
				if(c1 == -1)
					return -1;
				c+=c1;
				p+=c1;
			}
			break;
		case 'z'://time zone adjuctments
			{
				p++;
				c++;
				c1 = skipequal(p,len - c);
				if(c1 == -1)
					return -1;
				p+=c1;
				c+=c1;
				c1 = ParseUnknown(p,len-c);
				if(c1 == -1)
					return -1;
				c+=c1;
				p+=c1;
			}
			break;
		case 'k'://encryption key
			{
				p++;
				c++;
				c1 = skipequal(p,len - c);
				if(c1 == -1)
					return -1;
				p+=c1;
				c+=c1;
				c1 = ParseUnknown(p,len-c);
				if(c1 == -1)
					return -1;
				c+=c1;
				p+=c1;
			}
			break;
		case 'a'://att_field
			{
				p++;
				c++;
				c1 = skipequal(p,len - c);
				if(c1 == -1)
					return -1;
				p+=c1;
				c+=c1;
				struct Attribute a;
				c1 = ParseAttribute(p,len-c,a);
				if(c1 == -1)
					return -1;
				c+=c1;
				p+=c1;
				attributelist.push_back(a);
			}
			break;
		case 't'://time the session is active
			{
				p++;
				c++;
				c1 = skipequal(p,len - c);
				if(c1 == -1)
					return -1;
				p+=c1;
				c+=c1;
				if(times == NULL)
					times = new struct Times;
				c1 = ParseTimes(p,len-c,*times);
				if(c1 == -1)
					return -1;
				c+=c1;
				p+=c1;
			}
			break;
		case 'r'://zero or more repeat times
			{
				p++;
				c++;
				c1 = skipequal(p,len - c);
				if(c1 == -1)
					return -1;
				p+=c1;
				c+=c1;
				if(repeattimes == NULL)
					repeattimes = new struct RepeatTimes;
				c1 = ParseRepeatTimes(p,len-c,*repeattimes);
				if(c1 == -1)
					return -1;
				c+=c1;
				p+=c1;
			}
			break;
		case 'm'://media name and transport address
			{
				p++;
				c++;
				c1 = skipequal(p,len - c);
				if(c1 == -1)
					return -1;
				p+=c1;
				c+=c1;
				struct MediaDescription *md = new struct MediaDescription;
				md->bandwidth = NULL;
				md->connection = NULL;
				
				c1 = ParseMediaDescription(p,len-c,*md);
				if(c1 == -1)
				{
					delete md;
					return -1;
				}
				c+=c1;
				p+=c1;
				medialist.push_back(md);
			}
			break;
		default:
			{
				p++;
				c++;
				c1 = skipequal(p,len - c);
				if(c1 == -1)
					return -1;
				p+=c1;
				c+=c1;
				c1 = ParseUnknown(p,len-c);
				if(c1 == -1)
					return -1;
				c+=c1;
				p+=c1;
			}
			break;
		}
		if(c >= len)
			break;
	}
	return c;
}

int	CSDPContent::ParseVersion(const char *pbuf,int len,int &version)//v=
{//"v=" 1*DIGIT CRLF
	int c = 0;
	const char *p = pbuf;
	mystring str;
	while(*p)
	{
		if(*p == '\r')
			break;
		str += *p;
		p++;
		c++;
		if(c >= len)
		{
			version = atoi(str.c_str());
			return c;
		}		
	}
	if(str.empty() == false)
		version = atoi(str.c_str());
	else
		version = 0;
	//skip CRLF
	c+=2;
	return c;
}
int CSDPContent::ParseOrigin(const char *pbuf,int len,struct Origin &o)//o=
{//"o=" username space sess-id space sess-version space nettype space addrtype space addr CRLF
	const char *p = pbuf;
	int c = 0;
	mystring str;
	o.username.erase();
	while(*p)
	{
		if(*p == ' ')
			break;
		o.username += *p;
		p++;
		c++;
		if(c >= len)
			return -1;
	}
	//skip space
	p++;
	c++;
	if(c >= len)
		return -1;

	o.sessionid = 0;
	str.erase();
	while(*p)
	{
		if(*p == ' ')
			break;
		str += *p;
		p++;
		c++;
		if(c >= len)
			return -1;
	}
	if(str.empty() == false)
	{
		o.sessionid = atoi(str.c_str());		
	}
	//skip space
	p++;
	c++;
	if(c >= len)
		return -1;

	o.version = 0;
	str.erase();
	while(*p)
	{
		if(*p == ' ')
			break;
		str += *p;
		p++;
		c++;
		if(c >= len)
			return -1;
	}
	if(str.empty() == false)
	{
		o.version = atoi(str.c_str());		
	}
	//skip space
	p++;
	c++;
	if(c >= len)
		return -1;


	o.networktype.erase();	
	while(*p)
	{
		if(*p == ' ')
			break;
		o.networktype += *p;
		p++;
		c++;
		if(c >= len)
			return -1;
	}	
	//skip space
	p++;
	c++;
	if(c >= len)
		return -1;

	o.addresstype.erase();//IPV4/IPV6
	str.erase();
	while(*p)
	{
		if(*p == ' ')
			break;
		o.addresstype += *p;
		p++;
		c++;
		if(c >= len)
			return -1;
	}	
	//skip space
	p++;
	c++;
	if(c >= len)
		return -1;

	o.address.erase();	
	while(*p)
	{
		if(*p == '\r')
			break;
		o.address += *p;
		p++;
		c++;
		if(c >= len)
			return -1;
	}	
	//skip CRLF
	p+=2;
	c+=2;
	if(c > len)
		return -1;
	return c;
}
int CSDPContent::ParseSessionName(const char *pbuf,int len,mystring &s)//s=
{//"s=" text CRLF
	const char *p = pbuf;
	int c = 0;
	s.erase();
	while(*p)
	{
		if(*p == '\r')
			break;
		s += *p;
		p++;
		c++;
		if(c >= len)
			return -1;
	}
	//skip CRLF
	p+=2;
	c+=2;
	if(c > len)
		return -1;
	return c;
}

int CSDPContent::ParseSessionDescription(const char *pbuf,int len,mystring &i)//i=
{//"i=" text CRLF
	const char *p = pbuf;
	int c = 0;
	i.erase();
	while(*p)
	{
		if(*p == '\r')
			break;
		i += *p;
		p++;
		c++;
		if(c >= len)
			return -1;
	}
	//skip CRLF
	p+=2;
	c+=2;
	if(c > len)
		return -1;
	return c;
}
int CSDPContent::ParseURI(const char *pbuf,int len,mystring &u)//u=
{
	const char *p = pbuf;
	int c = 0;
	u.erase();
	while(*p)
	{
		if(*p == '\r')
			break;		
		u += *p;
		p++;
		c++;
		if(c >= len)
			return -1;
	}
	//skip CRLF
	p+=2;
	c+=2;
	if(c > len)
		return -1;
	return c;
}
int CSDPContent::ParseEMail(const char *pbuf,int len,mystring &e)//e=
{//"e=" email-address CRLF
	const char *p = pbuf;
	int c = 0;
	e.erase();
	while(*p)
	{
		if(*p == '\r')
			break;
		e += *p;
		p++;
		c++;
		if(c >= len)
			return -1;
	}
	//skip CRLF
	p+=2;
	c+=2;
	if(c > len)
		return -1;
	return c;
}
int CSDPContent::ParsePhoneNumber(const char *pbuf,int len,mystring &ph)//p=
{//"p=" phone-number CRLF
	const char *p = pbuf;
	int c = 0;
	ph.erase();
	while(*p)
	{
		if(*p == '\r')
			break;
		ph += *p;
		p++;
		c++;
		if(c >= len)
			return -1;
	}
	//skip CRLF
	p+=2;
	c+=2;
	if(c > len)
		return -1;
	return c;
}
int CSDPContent::ParseConnectionInformation(const char *pbuf,int len,struct Connection &cn)//c=
{//"c=" nettype space addrtype space connection-address CRLF
	const char *p = pbuf;
	int c = 0;
	cn.networktype.erase();//IN
	while(*p)
	{
		if(*p == ' ')
			break;
		cn.networktype += *p;
		p++;
		c++;
		if(c >= len)
			return -1;
	}
	//skip space
	p++;
	c++;
	if(c >= len)
		return -1;

	cn.addresstype.erase();//ipv4/ipv6
	while(*p)
	{
		if(*p == ' ')
			break;
		cn.addresstype += *p;
		p++;
		c++;
		if(c >= len)
			return -1;
	}
	//skip space
	p++;
	c++;
	if(c >= len)
		return -1;

	cn.connectionaddress.erase();
	while(*p)
	{
		if(*p == '\r')
			break;
		cn.connectionaddress += *p;
		p++;
		c++;
		if(c >= len)
			return -1;
	}
	//skip CRLF
	p+=2;
	c+=2;
	if(c > len)
		return -1;
	return c;
}
int CSDPContent::ParseBandwidthInformation(const char *pbuf,int len,struct Bandwidth &b)//b=
{//"b=" bwtype ":" bandwidth CRLF
	int c = 0;
	const char *p = pbuf;
	b.modifier.erase();
	while(*p)
	{
		if(*p == ':')
			break;
		b.modifier+=*p;
		p++;
		c++;
		if(c >= len)
			return -1;
	}
	p++;
	c++;
	b.bandwidthvalue = 0;
	mystring str;
	while(*p)
	{
		if(*p == '\r')
			break;
		str += *p;
		p++;
		c++;
		if(c >= len)
			return -1;
	}
	p+=2;
	c+=2;
	if(str.empty() == false)
	{
		b.bandwidthvalue = atoi(str.c_str());
	}
	return c;
}
int CSDPContent::ParseAttribute(const char *pbuf,int len,struct Attribute &a)//a=
{//"a=" att_field CRLF
//att_field = (att-field ":" att-att_value) | att-=field
	int c = 0;
	const char *p = pbuf;
	a.att_field.erase();
	while(*p)
	{
		if(*p == ':' || *p == '\r')
			break;
		a.att_field += *p;
		p++;
		c++;
		if(c >= len)
			return -1;
	}
	a.att_value.erase();
	if(*p == ':')
	{
		p++;
		c++;
		while(*p)
		{
			if(*p == '\r')
				break;
			a.att_value += *p;
			p++;c++;
			if(c >= len)
				return -1;
		}
	}
	p+=2;
	c+=2;
	return c;
}
int CSDPContent::ParseTimes(const char *pbuf,int len,struct Times&t)//t=
{//"t=" start-time space stop-time
	int c;
	c = 0;
	return c;
}
int CSDPContent::ParseRepeatTimes(const char *pbuf,int len,struct RepeatTimes &r)//r=
{//"r=" repeat-interval space typed-time 1*(space typed-time)
	int c = 0;
	const char *p = pbuf;
	r.repeatinterval = 0;
	mystring str;
	while(*p)
	{
		if(*p == ' ')
			break;
		str += *p;
		p++;c++;
		if(c >= len)
			return -1;
	}
	if(str.empty() == false)
		r.repeatinterval = atoi(str.c_str());
	p++;
	c++;
	if(c >= len)
		return -1;

	str.erase();
	r.activeduration = 0;
	while(*p)
	{
		if(*p == ' ' || *p == '\r')
			break;
		str += *p;
		p++;c++;
		if(c >= len)
			return -1;
	}
	if(str.empty() == false)
		r.activeduration = atoi(str.c_str());
	while(*p == ' ')
	{
		p++;
		c++;
		if(c >= len)
			return -1;
		str.erase();
		while(*p)
		{
			if(*p == ' ' || *p == '\r')
				break;
			str += *p;
			p++;c++;
			if(c >= len)
				return -1;
		}
		r.offsetlist.push_back(atoi(str.c_str()));
	}
	p+=2;
	c+=2;
	if(c > len)
		return -1;
	return c;
}
int CSDPContent::ParseMedia(const char *pbuf,int len,struct Media &m)//m=
{//"m=" media space port ["/" integer] space proto 1*(space fmt) CRLF
	int c = 0;
	const char *p = pbuf;
	mystring str;
	m.media.erase();
	while(*p)
	{
		if(*p == ' ')
			break;
		m.media +=*p;
		p++;c++;
		if(c >= len)
			return -1;
	}
	p++;c++;
	if(c >= len)
		return -1;
	m.port = 0;
	while(*p)
	{
		if(*p == ' ' || *p == '/')
			break;
		str += *p;
		p++;c++;
		if(c >= len)
			return -1;
	}
	if(str.empty() == false)
	{
		m.port = atoi(str.c_str());
		str.erase();
	}
	m.numberofport = 0;
	if(*p == '/')
	{//has integer
		p++;c++;
		if(c >= len)
			return -1;
		while(*p)
		{
			if(*p == ' ')
				break;
			str += *p;
			p++;c++;
			if(c >= len)
				return -1;
		}
		if(str.empty() == false)
		{
			m.numberofport = atoi(str.c_str());
			str.erase();
		}
	}
	p++;c++;
	if(c >= len)
		return -1;
	while(*p)
	{
		if(*p == ' ' || *p == '\r')
			break;
		m.transport += *p;
		p++;c++;
		if(c >= len)
			break;
	}
	while(*p == ' ')
	{//has format
		p++;c++;
		if(c >= len)
			return -1;
		str.erase();
		while(*p)
		{
			if(*p == ' ' || *p == '\r')
				break;
			str += *p;
			p++;c++;
			if(c >= len)
				return -1;
		}
		m.formatlist.push_back(str);
	}
	p+=2;
	c+=2;
	return c;
}
int CSDPContent::ParseMediaDescription(const char *pbuf,int len,struct MediaDescription &md)
{//
	const char *p = pbuf;
	int c = 0,c1;
	c1 = ParseMedia(p,len-c,md.media);
	if(c1 == -1)
		return -1;
	c+=c1;
	p+=c1;
	while(1)
	{
		if(*p == 'i')
		{
			p++;
			c++;
			c1 = skipequal(p,len - c);
			if(c1 == -1)
				return -1;
			p+=c1;
			c+=c1;
			c1 = ParseSessionDescription(p,len - c,md.mediatitle);
			if(c1 == -1)
				return -1;
			c+=c1;
			p+=c1;
			if(c > len)
				return -1;
			else if(c == len)
				return c;
		}
		else if(*p == 'c')
		{
			p++;
			c++;
			c1 = skipequal(p,len - c);
			if(c1 == -1)
				return -1;
			p+=c1;
			c+=c1;
			if(md.connection == NULL)
				md.connection = new struct Connection;
			c1 = ParseConnectionInformation(p,len - c,*md.connection);
			if(c1 == -1)
				return -1;
			c+=c1;
			p+=c1;
			if(c > len)
				return -1;
			else if(c == len)
				return c;
		}
		else if(*p == 'b')
		{
			p++;
			c++;
			c1 = skipequal(p,len - c);
			if(c1 == -1)
				return -1;
			p+=c1;
			c+=c1;
			if(md.bandwidth == NULL)
				md.bandwidth = new struct Bandwidth;
			c1 = ParseBandwidthInformation(p,len - c,*md.bandwidth);
			if(c1 == -1)
				return -1;
			c+=c1;
			p+=c1;
			if(c > len)
				return -1;
			else if(c == len)
				return c;
		}
		else if(*p == 'k')
		{
			p++;
			c++;
			c1 = skipequal(p,len - c);
			if(c1 == -1)
				return -1;
			p+=c1;
			c+=c1;
			c1 = ParseUnknown(p,len -c);
			if(c1 == -1)
				return -1;
			c+=c1;
			p+=c1;
			if(c > len)
				return -1;
			else if(c == len)
				return c;
		}
		else if(*p == 'a')
		{
			p++;
			c++;
			c1 = skipequal(p,len - c);
			if(c1 == -1)
				return -1;
			p+=c1;
			c+=c1;

			struct Attribute attr;
			c1 = ParseAttribute(p,len - c,attr);
			if(c1 == -1)
				return -1;
			c+=c1;
			p+=c1;
			if(c > len)
				return -1;
			else if(c == len)
			{
				md.attributelist.push_back(attr);
				return c;
			}
			md.attributelist.push_back(attr);
		}
		else if(*p == 'm')		
			break;
		else
		{
			return -1;
		}
	}
	return c;
}

int CSDPContent::ParseUnknown(const char *p,int len)
{
	int c;
	c = 0;
	return c;
}

CSDPContent& CSDPContent::operator=(const CSDPContent& rhs)
{
	Clear();
	CSIPContent::Clear();
	if(rhs.origin)
	{			
		origin = new struct Origin;
		*origin = *rhs.origin;
	}
	if(rhs.connection)
	{			
		connection = new struct Connection;
		*connection = *rhs.connection;
	}
	if(rhs.bandwidth)
	{			
		bandwidth = new struct Bandwidth;
		*bandwidth = *rhs.bandwidth;
	}
	if(rhs.times)
	{			
		times = new struct Times;
		*times = *rhs.times;
	}
	if(rhs.repeattimes)
	{			
		repeattimes = new struct RepeatTimes;
		*repeattimes = *rhs.repeattimes;
	}
	
	while(attributelist.empty() == false)
	{
		attributelist.pop_front();
	}
	m_nLength = rhs.m_nLength;
	if(rhs.m_pContent)
	{
		m_pContent = new char[rhs.m_nLength+1];
		memcpy(m_pContent,rhs.m_pContent,rhs.m_nLength);		
		m_pContent[m_nLength] = '\0';
	}
	return *this;
}		
